﻿using System;
using System.Collections.Generic;
using System.Text;
using iTunesLib;
using System.Threading;
using SimpleSerial;

namespace iTunes
{
    class Engine
    {

        private string RxString;
        //senseurs & pic
        private IR IR1;
        private IR IR2;
        private bool butonCoverFlow;
        //thread
        private Thread threadAnalyse;
        private Thread threadIR;
        private Thread threadIR1;
        private Thread threadIR2;
       
        private iTunesApp m_iTunes;
       
        private System.IO.Ports.SerialPort serialPort;
        
        public Engine()
        {
            butonCoverFlow = false;
            IR1 = new IR();
            IR2 = new IR();
            m_iTunes = new iTunesApp();

            
            this.serialPort = new System.IO.Ports.SerialPort("COM1", 2400, Parity.None, 8, StopBits.One);
            serialPort.Handshake = Handshake.None;
            // this.serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPortDataReceived);

            // Instanciation du thread, on spécifie dans le 
            // délégué ThreadStart le nom de la méthode qui
            // sera exécutée lorsque l'on appele la méthode
            // Start() de notre thread.
            threadAnalyse = new Thread(new ThreadStart(loop));
        }
<<<<<<< .mine

        //fonction appellée lors de la réception de données
        //sensée remplir les tableaux tabIR1 et tabIR2
        //a chaque donnée reçue, on la met dans un tableau de l'infrarouge correspondant

        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //lit ce qu'il y a sur le port COM1 
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;

            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);

            if (result)
            {
                //Console.WriteLine("Converted '{0}' to {1}.", RxString, n);
                RxString = n.ToString();
                //si la valeur est 0
                //on change la valeur du bouton qui controle le coverflow
                if (RxString.Equals("0"))
                {
                    if (eng.getButonCoverFlow()) eng.setButonCoverFlow(false);
                    else eng.setButonCoverFlow(true);
                }

                // si la valeur est celle de IR1
                else if (RxString.StartsWith("1"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    getIR1().getTab().Add(n);

                    //graphing
                    Graphics objGraphic = this.pictureBox1.CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = pictureBox1.Size.Width;
                    rec.Height = pictureBox1.Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = pictureBox1.Size.Height - n * pictureBox1.Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);

                    RxString = "ajout ds tab de IR1 de " + n;
                }
                // si la valeur est celle de IR2
                else if (RxString.StartsWith("2"))
                {
                    //n contient l'entier
                    //on enleve le 2
                    if (n <= 29) n = n - 20;
                    else if (n <= 299) n = n - 200;
                    else if (n <= 2999) n = n - 2000;
                    else if (n <= 29999) n = n - 20000;

                    getIR2().getTab().Add(n);

                    // graphing
                    Graphics objGraphic = this.pictureBox2.CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = pictureBox1.Size.Width;
                    rec.Height = pictureBox1.Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = pictureBox1.Size.Height - n * pictureBox1.Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);

                    RxString = "ajout ds tab de IR2 de " + n;
                }
                else
                {
                    RxString = "Valeure non conforme";
                }
            }
            else
            {
                //RxString = "ERROR PARSING";
            }
            //this.Invoke(new EventHandler(DisplayText));
        }
=======
>>>>>>> .r169

<<<<<<< .mine
        public void threadIR1Loop()
        {

            //write command to pic

            string s = "get1";

            try
            {
                if (!(_serialPort.IsOpen))
                    serialPort.Open();
                serialPort.Write(s);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
            }

            //result received 
            string RxString;
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;

            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);

            if (result)
            {
                if (RxString.StartsWith("1"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    //update IR1
                    getIR1().Add(n);

                    //graphing
                    Graphics objGraphic = form.getpictureBox1().CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = form.getpictureBox1().Size.Width;
                    rec.Height = form.getpictureBox1().Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = form.getpictureBox1().Size.Height - n * form.getpictureBox1().Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);
                }
                else
                {

                }
            }
            else
            {
            }

        }
=======
        //fonction appellée lors de la réception de données
        //sensée remplir les tableaux tabIR1 et tabIR2
        //a chaque donnée reçue, on la met dans un tableau de l'infrarouge correspondant
>>>>>>> .r169

<<<<<<< .mine
        public void threadIR2Loop()
=======
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
>>>>>>> .r169
        {
<<<<<<< .mine

            //write command to pic

            string s = "get2";

            try
            {
                if (!(_serialPort.IsOpen))
                    serialPort.Open();
                serialPort.Write(s);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
            }

            //result received 
            string RxString;
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;

            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);

            if (result)
            {
                if (RxString.StartsWith("2"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    //update IR1
                    getIR2().Add(n);

                    //graphing
                    Graphics objGraphic = form.getpictureBox2().CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = form.getpictureBox2().Size.Width;
                    rec.Height = form.getpictureBox2().Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = form.getpictureBox2().Size.Height - n * form.getpictureBox2().Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);
                }
                else
                {

                }
            }
            else
            {
            }

        }
=======
            //lit ce qu'il y a sur le port COM1 
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;
>>>>>>> .r169

<<<<<<< .mine
        public void threadIRLoop()
        {
            //thread IR1
            Console.WriteLine("Demarrage du thread IR1");
            threadIR1 = new Thread(new ThreadStart(threadIR1Loop));
            threadIR1.Start();
            threadIR1.Join();
            Console.WriteLine("Fin du thread IR1");
  
            //thread IR2
            Console.WriteLine("Demarrage du thread IR2");
            threadIR2 = new Thread(new ThreadStart(threadIR2Loop));
            threadIR2.Start();
            threadIR2.Join();
            Console.WriteLine("Fin du thread IR2");
=======
            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);
>>>>>>> .r169

<<<<<<< .mine
        }
        //thread principal qui construit le systeme pour 5 mesures de chaque IR, regarde si les mesures sont conformes et si elles le sont,
        //lance lanalyse des IR
        public void loop()
        {
            for (int i = 0; i < 5; i++)
            {
                //thread mesures IR
                Console.WriteLine("Demarrage du thread de mesure");
                threadIR = new Thread(new ThreadStart(threadIRLoop));
                threadIR.Start();
                threadIR.Join();
                Console.WriteLine("Fin du thread de mesure");
            }

            //si au bout des 5 mesures les valeurs ne sont pas interessantes (moy<50) on crée des nouveaux objets IR
            if (IR1.getTab().Count = 5 && IR2.getTab().Count = 5 && IR1.getAverage() < 50 && IR2.getAverage() < 50)
            {
                IR1 = new IR();
                IR2 = new IR();
            }
            //sinon on lance le thread danalyse
            else
            {
                //thread analyse
                Console.WriteLine("Demarrage du thread d'analyse");
                threadAnalyse = new Thread(new ThreadStart(threadAnalLoop));
                threadAnalyse.Start();
                threadAnalyse.Join();
                Console.WriteLine("Fin du thread d'analyse");
            }
        }

        //fonction utilisée pour le  thread
        public void threadAnalLoop()
        {
            if (IR1.isOn() && IR2.isOn())
=======
            if (result)
>>>>>>> .r169
            {
<<<<<<< .mine
                Console.WriteLine("IR1");
                Console.WriteLine("has " + IR1.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR1.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR1.getLastChangeIndex());
                Console.WriteLine("IR2");
                Console.WriteLine("has " + IR2.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR2.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR2.getLastChangeIndex()); 
                Console.WriteLine("CheckOrder is " + this.checkOrder());
                Console.WriteLine("CheckOverlap is " + this.checkOverlap());
                //Console.WriteLine("CheckStop is " + this.checkStop());
            }
            else if (IR1.isOn())
            {
                Console.WriteLine("IR1");
                Console.WriteLine("has " + IR1.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR1.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR1.getLastChangeIndex());
                Console.WriteLine("CheckPlay is " + this.checkPlay());
            }
            else if (IR2.isOn())
            {
                Console.WriteLine("IR2");
                Console.WriteLine("has " + IR2.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR2.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR2.getLastChangeIndex());
                Console.WriteLine("CheckIR2 is " + this.checkIR2());
            }
            else Console.WriteLine("Aucun IR n est considere allume");

        }
=======
                //Console.WriteLine("Converted '{0}' to {1}.", RxString, n);
                RxString = n.ToString();
                //si la valeur est 0
                //on change la valeur du bouton qui controle le coverflow
                if (RxString.Equals("0"))
                {
                    if (eng.getButonCoverFlow()) eng.setButonCoverFlow(false);
                    else eng.setButonCoverFlow(true);
                }
>>>>>>> .r169

                // si la valeur est celle de IR1
                else if (RxString.StartsWith("1"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    getIR1().getTab().Add(n);

                    //graphing
                    Graphics objGraphic = this.pictureBox1.CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = pictureBox1.Size.Width;
                    rec.Height = pictureBox1.Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

<<<<<<< .mine
=======
                    rec.Height = pictureBox1.Size.Height - n * pictureBox1.Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);

>>>>>>> .r169
                    RxString = "ajout ds tab de IR1 de " + n;
                }
                // si la valeur est celle de IR2
                else if (RxString.StartsWith("2"))
                {
                    //n contient l'entier
                    //on enleve le 2
                    if (n <= 29) n = n - 20;
                    else if (n <= 299) n = n - 200;
                    else if (n <= 2999) n = n - 2000;
                    else if (n <= 29999) n = n - 20000;

                    getIR2().getTab().Add(n);

                    // graphing
                    Graphics objGraphic = this.pictureBox2.CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = pictureBox1.Size.Width;
                    rec.Height = pictureBox1.Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = pictureBox1.Size.Height - n * pictureBox1.Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);

                    RxString = "ajout ds tab de IR2 de " + n;
                }
                else
                {
                    RxString = "Valeure non conforme";
                }
            }
            else
            {
                //RxString = "ERROR PARSING";
            }
            //this.Invoke(new EventHandler(DisplayText));
        }

        public void threadIR1Loop()
        {

            //write command to pic

            string s = "get1";

            try
            {
                if (!(_serialPort.IsOpen))
                    serialPort.Open();
                serialPort.Write(s);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
            }

            //result received 
            string RxString;
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;

            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);

            if (result)
            {
                if (RxString.StartsWith("1"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    //update IR1
                    getIR1().Add(n);

                    //graphing
                    Graphics objGraphic = form.getpictureBox1().CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = form.getpictureBox1().Size.Width;
                    rec.Height = form.getpictureBox1().Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = form.getpictureBox1().Size.Height - n * form.getpictureBox1().Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);
                }
                else
                {

<<<<<<< .mine
            // Indice de la liste à partir duquel on commence à copier les valeurs
            int debutSelection = IR2.getFirstChangeIndex();
            int finSelection = IR2.getLastChangeIndex();

            //On convertit la liste de string en liste de double
            List<double> analyse = tableauBCheck.ConvertAll(new Converter<int, double>(intToDouble)); //a supprimer

            //double DiffIR2;
            int DiffIR2;

            //valeur qui stocke la différence de distance entre avant evenement et après evenement 
            //(première valeur et dernière valeur du segment selectionné plus tôt)
            //DiffIR2 = analyse[finSelection - 1] - analyse[debutSelection];
            DiffIR2 = tableauBCheck[finSelection] - tableauBCheck[debutSelection];

            if (DiffIR2 != 0)
                //on cherche le coeff directeur de la variation
                //double DiffVol = (NbACopier / DiffIR2);
                DiffVol = (long)(NbACopier / DiffIR2);
            else DiffVol = 0;
            return DiffVol;
        }

        //Cette fonction analyse les changements de IR1 pour déterminer
        //s'il y a besoin de faire play/pause
        int checkPlay()
        {
            // Longueur du segment à analyser
            int nbACopier = IR1.getLastChangeIndex() - IR1.getFirstChangeIndex();
            // Valeur retournée: 0 si l'action est play, 1 si pause
            int res = 0;
            int cmp = 0;
            // Compte les fois où les conditions du mouvement est vérifiée
            int compteur = 0;

            // Création d'une liste de int
            // On copie tab1 dans cette liste
            List<int> aAnalyser = new List<int>(IR1.getTab());
            // On cherche le premier changement    
            int firstChangeIndex = IR1.getFirstChangeIndex();
            // On enlève tout ce qu'il y a avant
            aAnalyser.RemoveRange(0, firstChangeIndex);
            //On convertit la liste de int en liste de double
            List<double> tabConvert = aAnalyser.ConvertAll(new Converter<int, double>(intToDouble));
            // On teste toutes les valeurs de la liste
            for (int i = 1; i <= nbACopier; i++)
=======
                }
            }
            else
>>>>>>> .r169
            {
            }

        }

<<<<<<< .mine
        //Cette fonction analyse les changements de IR1 et IR2 pour déterminer
        //s'il y a besoin de faire stop
        bool checkStop()
=======
        public void threadIR2Loop()
>>>>>>> .r169
        {

            //write command to pic

            string s = "get2";

            try
            {
                if (!(_serialPort.IsOpen))
                    serialPort.Open();
                serialPort.Write(s);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
            }

            //result received 
            string RxString;
            try
            {
                RxString = serialPort.ReadLine();
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            int n;

            //result resultat du tryparse
            //si true parsage a ete fait correctement
            bool result = int.TryParse(RxString, out n);

            if (result)
            {
                if (RxString.StartsWith("2"))
                {
                    //n contient l'entier
                    //on enleve le 1
                    if (n <= 19) n = n - 10;
                    else if (n <= 199) n = n - 100;
                    else if (n <= 1999) n = n - 1000;
                    else if (n <= 19999) n = n - 10000;

                    //update IR1
                    getIR2().Add(n);

                    //graphing
                    Graphics objGraphic = form.getpictureBox2().CreateGraphics();
                    Pen pen = new Pen(Color.Black);
                    Rectangle rec = new Rectangle();
                    rec.Width = form.getpictureBox2().Size.Width;
                    rec.Height = form.getpictureBox2().Size.Height;
                    objGraphic.FillRectangle(Brushes.Black, rec);

                    rec.Height = form.getpictureBox2().Size.Height - n * form.getpictureBox2().Size.Height / 1002;
                    objGraphic.FillRectangle(Brushes.White, rec);
                }
                else
                {

                }
            }
            else
            {
            }

        }

        public void threadIRLoop()
        {
            //thread IR1
            Console.WriteLine("Demarrage du thread IR1");
            threadIR1 = new Thread(new ThreadStart(threadIR1Loop));
            threadIR1.Start();
            threadIR1.Join();
            Console.WriteLine("Fin du thread IR1");
  
            //thread IR2
            Console.WriteLine("Demarrage du thread IR2");
            threadIR2 = new Thread(new ThreadStart(threadIR2Loop));
            threadIR2.Start();
            threadIR2.Join();
            Console.WriteLine("Fin du thread IR2");

        }
        //thread principal qui construit le systeme pour 5 mesures de chaque IR, regarde si les mesures sont conformes et si elles le sont,
        //lance lanalyse des IR
        public void loop()
        {
            for (int i = 0; i < 5; i++)
            {
                //thread mesures IR
                Console.WriteLine("Demarrage du thread de mesure");
                threadIR = new Thread(new ThreadStart(threadIRLoop));
                threadIR.Start();
                threadIR.Join();
                Console.WriteLine("Fin du thread de mesure");
            }

            //si au bout des 5 mesures les valeurs ne sont pas interessantes (moy<50) on crée des nouveaux objets IR
            if (IR1.getTab().Count = 5 && IR2.getTab().Count = 5 && IR1.getAverage() < 50 && IR2.getAverage() < 50)
            {
                IR1 = new IR();
                IR2 = new IR();
            }
            //sinon on lance le thread danalyse
            else
            {
                //thread analyse
                Console.WriteLine("Demarrage du thread d'analyse");
                threadAnalyse = new Thread(new ThreadStart(threadAnalLoop));
                threadAnalyse.Start();
                threadAnalyse.Join();
                Console.WriteLine("Fin du thread d'analyse");
            }
        }

        //fonction utilisée pour le  thread
        public void threadAnalLoop()
        {
            if (IR1.isOn() && IR2.isOn())
            {
                Console.WriteLine("IR1");
                Console.WriteLine("has " + IR1.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR1.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR1.getLastChangeIndex());
                Console.WriteLine("IR2");
                Console.WriteLine("has " + IR2.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR2.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR2.getLastChangeIndex()); 
                Console.WriteLine("CheckOrder is " + this.checkOrder());
                Console.WriteLine("CheckOverlap is " + this.checkOverlap());
                //Console.WriteLine("CheckStop is " + this.checkStop());
            }
            else if (IR1.isOn())
            {
                Console.WriteLine("IR1");
                Console.WriteLine("has " + IR1.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR1.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR1.getLastChangeIndex());
                Console.WriteLine("CheckPlay is " + this.checkPlay());
            }
            else if (IR2.isOn())
            {
                Console.WriteLine("IR2");
                Console.WriteLine("has " + IR2.getTab().Count + " values.");
                Console.WriteLine("first change index is " + IR2.getFirstChangeIndex());
                Console.WriteLine("last change index is " + IR2.getLastChangeIndex());
                Console.WriteLine("CheckIR2 is " + this.checkIR2());
            }
            else Console.WriteLine("Aucun IR n est considere allume");

        }

        #region getters, setters
        public void setThread(Thread val)
        {
            this.threadAnalyse = val;
        }

        public Thread getThread()
        {
            return this.threadAnalyse;
        }

        public void setButonCoverFlow(bool val)
        {
            this.butonCoverFlow = val;
        }

        public bool getButonCoverFlow()
        {
            return this.butonCoverFlow;
        }

        public void setIR1(IR obj)
        {
            IR1 = obj;
        }

        public void setIR2(IR obj)
        {
            IR2 = obj;
        }

        public IR getIR1()
        {
            return IR1;
        }

        public IR getIR2()
        {
            return IR2;
        }
        #endregion

<<<<<<< .mine
        public void setThread(Thread val)
        {
            this.threadAnalyse = val;
        }

        public Thread getThread()
        {
            return this.threadAnalyse;
        }

=======
>>>>>>> .r169
        public void setButonCoverFlow(bool val)
        {
            this.butonCoverFlow = val;
        }

        public bool getButonCoverFlow()
        {
            return this.butonCoverFlow;
        }

        public void setIR1(IR obj)
        {
            IR1 = obj;
        }

        public void setIR2(IR obj)
        {
            IR2 = obj;
        }

        public IR getIR1()
        {
            return IR1;
        }

        public IR getIR2()
        {
            return IR2;
        }
        
    }
}
